【Dart 教程系列第 49 篇】Dart 是值传递还是引用传递
九黎侍者:
我觉得,事情并没有这么复杂,都是引用传递。因为 Dart 中任何类型的变量都是引用,见 https://dart.cn/guides/language/language-tour#variables 。传参和赋值语句中,不管是基础类型(int,double)还是复合类型(class)都是把对象存放的引用赋值给变量或者形参,也就都是引用传递。
这时你可能会说,既然都是引用传递,为什么基础类型表现得像 C 中的值传递,而复合类型表现得却像引用传递?
对于复合类型,看似表现得像引用传递,其实不然,它并没有像基础类型的引用(指C语言或者PHP)一样的功能,因为你修改的是变量指向的复合类型中的某个属性而已,而不是修改了这个变量。如果你来个 "var a=new People();var b=a; b=new People();",你就看到它和基础类型表现就一致了。事实上,大部分有面向对象特性的语言,复合类型的变量的参数传递时,传递都是对象的引用。
如果是有引用类型的语言,如 PHP 或者 C++ “var a=new People();var b=&a; b=new People(); ”这样的结果是,a 和 b 都指向同一个对象。
重点在于“变量仅存储对象的引用”,如 “int a=20” 这里的变量 a,实际上, Dart 先创建一个 Int 对象,再将其引用赋值给 a,所以,如“int a=20;int b=a;b=30;” 这样的语句,并不能表现出 C 语言或者其它有“引用类型”语言所表现的效果(a 不会和 b 一样等于 30)。
对于复合对象,如果你也是 "var a=new People();var b=a; b=new People();" 这样的语句,你也改变不了 a。
所以,看起来基础类型和复合类型表现不一致,只是因为使用的方式不同而已。在传参或者赋值时,都是引用传递,并没有区别。不过因为你修改基础类型参数时,直接把变量的引用改了(a=20;a=30),而修改复合类型时,只是改了它的某个属性(a.size=20;a.size=30)。
|